deferred class IUP_WIDGET_INTERNALS
-- Internals commands.

inherit
	IUP_WIDGET
		undefine
			execute_map,
			execute_unmap,
			execute_destroy,
			execute_getfocus,
			execute_killfocus,
			execute_enterwindow,
			execute_leavewindow,
			execute_k_any,
			execute_help,
			execute_action,
			execute_close,
			execute_copydata,
			execute_dropfiles,
			execute_mdiactivate,
			execute_move,
			execute_resize,
			execute_show,
			execute_trayclick,
			execute_file,
			execute_colorupdate,
			execute_cancel,
			execute_button,
			execute_valuechanged,
			execute_action_fnff,
			execute_focus,
			execute_motion,
			execute_keypress,
			execute_scroll,
			execute_wheel,
			execute_detached,
			execute_restored,
			execute_openclose,
			execute_extrabutton,
			execute_click,
			execute_action_fnsii,
			execute_caret,
			execute_dblclick,
			execute_dragdrop,
			execute_dropdown,
			execute_edit,
			execute_multiselect,
			execute_spin,
			execute_tabchange,
			execute_tabchangepos,
			execute_tabclose,
			execute_rightclick,
			execute_action_fnis,
			execute_maskfail,
			execute_action_fni,
			execute_selection,
			execute_multiselection,
			execute_multiunselection,
			execute_branchopen,
			execute_branchclose,
			execute_executeleaf,
			execute_showrename,
			execute_rename,
			execute_noderemoved,
			execute_togglevalue,
			execute_highlight,
			execute_open,
			execute_menuclose,
			execute_dragbegin,
			execute_dragdatasize,
			execute_dragdata,
			execute_dragend,
			execute_dropdata,
			execute_dropmotion,
			execute_recent,
			execute_param,
			execute_flat_action,
			execute_flat_button,
			execute_flat_focus,
			execute_flat_enterwindow,
			execute_flat_leavewindow,
			execute_draw,
			execute_height,
			execute_hspan,
			execute_mouseclick,
			execute_mousemotion,
			execute_ncols,
			execute_nlines,
			execute_scrolling,
			execute_vspan,
			execute_width,
			execute_cell,
			execute_extended,
			execute_select,
			execute_switch,
			execute_action_fniiiis,
			execute_click_fniis,
			execute_colresize,
			execute_release,
			execute_resizematrix,
			execute_mousemove,
			execute_enteritem,
			execute_leaveitem,
			execute_scrolltop,
			execute_bgcolor,
			execute_fgcolor,
			execute_font,
			execute_type,
			execute_dropcheck,
			execute_translatevalue,
			execute_togglevalue_fniii,
			execute_drop,
			execute_menudrop,
			execute_dropselect,
			execute_edition,
			execute_value,
			execute_value_edit,
			execute_mark,
			execute_markedit,
			execute_flat_motion,
			execute_dropshow,
			execute_button_press,
			execute_button_release,
			execute_mousemove_fnd,
			execute_change,
			execute_drag
		end

insert
	IUP_INTERFACE

feature {}
	
	yesno_to_boolean (value: STRING): BOOLEAN
		do
			if value.is_equal("YES") then
				Result := True
			else
				Result := False
			end
		end

	boolean_to_yesno (value: BOOLEAN): STRING
		do
			if value then
				Result := "YES"
			else
				Result := "NO"
			end
		end
	
	is_yes_no (value: STRING): BOOLEAN
		do
			if value.is_equal("YES") or value.is_equal("NO") then
				Result := True
			else
				Result := False
			end
		end

	is_yes_no_ignore (value: STRING): BOOLEAN
		do
			if is_yes_no(value) or value.is_equal("IGNORE") then
				Result := True
			else
				Result := False
			end
		end

	is_valid_expand (value: STRING): BOOLEAN
		do
			if is_yes_no(value) or value.is_equal("HORIZONTAL") or
				value.is_equal("HORIZONTALFREE") or
				value.is_equal("VERTICAL") or
				value.is_equal("VERTICALFREE") then
				Result := True
			else
				Result := False
			end
		end

	is_valid_rgb_string (color: STRING): BOOLEAN
		local
			values: ARRAY[STRING]
			r, g, b: INTEGER
		do
			values := color.split

			if values.count.is_equal(3) then
				
				if values.item(1).is_integer and
					values.item(2).is_integer and
					values.item(3).is_integer then
					
					r := values.item(1).to_integer
					g := values.item(2).to_integer
					b := values.item(3).to_integer
					
					if r >= 0 and r <= 255 and
						g >= 0 and g <= 255 and
						b >= 0 and b <= 255 then
						Result := True
					end
				end
			end
		end

	is_valid_hexadecimal (value: STRING): BOOLEAN
		require
			sharp: value.has_prefix("#")
		   number_of_colors: value.count.is_equal(7)
		do
			value.remove_prefix("#")

			if value.for_all(agent {CHARACTER}.is_hexadecimal_digit) then
				Result := True
			else
				Result := False
			end
		end
	
	rgb_to_string (red, green, blue: INTEGER): STRING
		require
			red >= 0
			red <= 255
			green >= 0
			green <= 255
			blue >= 0
			blue <= 255
		local
			color: STRING
		do
			color := red.to_string
			color.append_string(" ")
			color.append_string(green.to_string)
			color.append_string(" ")
			color.append_string(blue.to_string)

			Result := color
		end

	rgba_to_string (red, green, blue, alpha: INTEGER): STRING
		require
			alpha >= 0
			alpha <= 255
		local
			color: STRING
		do
			color := rgb_to_string(red, green, blue)
			color.append_string(" ")
			color.append_string(alpha.to_string)

			Result := color
		end

	hsi_to_string (h, s, i: INTEGER): STRING
		require
			h >= 0
			h <= 359
			s >= 0
			s <= 100
			i >= 0
			i <= 100
		local
			color: STRING
		do
			color := h.to_string
			color.append_string(" ")
			color.append_string(s.to_string)
			color.append_string(" ")
			color.append_string(i.to_string)

			Result := color
		end

	hsi_real_to_string (h, s, i: REAL_64): STRING
		require
			h >= 0
			h <= 360
			s >= 0
			s <= 1
			i >= 0
			i <= 1
		local
			color: STRING
		do
			color := h.to_string
			color.append_string(" ")
			color.append_string(s.to_string)
			color.append_string(" ")
			color.append_string(i.to_string)

			Result := color
		end

	rgb_to_hexadecimal (red, green, blue: INTEGER): STRING
		require
			red >= 0
			red <= 255
			green >= 0
			green <= 255
			blue >= 0
			blue <= 255
		local
			c: INTEGER
			color, rs, gs, bs: STRING
		do
			color := "#"
			
			rs := red.to_hexadecimal
			gs := green.to_hexadecimal
			bs := blue.to_hexadecimal

			c := rs.count
			if c > 2 then
				rs.remove_head(c - 2)
			end

			c := gs.count
			if c > 2 then
				gs.remove_head(c - 2)
			end

			c := bs.count
			if c > 2 then
				bs.remove_head(c - 2)
			end

			color.append_string(rs)
			color.append_string(gs)
			color.append_string(bs)

			Result := color
		end

	hexadecimal_to_rgb (color: STRING): TUPLE[INTEGER, INTEGER, INTEGER]
		require
			valid_color: is_valid_hexadecimal(color)
		local
			r, g, b, base: NUMBER
			tup: TUPLE[INTEGER, INTEGER, INTEGER]
		do
			base := 16.to_number
			
			r := color.item(1).hexadecimal_value.to_number * base +
				color.item(2).hexadecimal_value.to_number
			g := color.item(3).hexadecimal_value.to_number * base +
				color.item(4).hexadecimal_value.to_number
			b := color.item(5).hexadecimal_value.to_number * base +
				color.item(6).hexadecimal_value.to_number

			tup := [r.to_integer_32, g.to_integer_32, b.to_integer_32]
			Result := tup
		end

	string_to_rgb (color: STRING): TUPLE[INTEGER, INTEGER, INTEGER]
		local
			values: ARRAY[STRING]
			tup: TUPLE[INTEGER, INTEGER, INTEGER]
		do
			values := color.split

			if values.count.is_equal(3) then
				
				if values.item(1).is_integer and
					values.item(2).is_integer and
					values.item(3).is_integer then
					tup := [values.item(1).to_integer, values.item(2).to_integer,
					        values.item(3).to_integer]
					Result := tup
				else
					io.put_string("Something goes wrong %N")
				end
			end
		end

	components_of (size: STRING; separator: CHARACTER): TUPLE[INTEGER, INTEGER]
		local
			i, c: INTEGER
			width, height: STRING
			tup: TUPLE[INTEGER, INTEGER]
		do
			if size.has(separator) then
				i := size.index_of(separator, 1)
				c := size.count

				--io.put_string(size)
				--io.put_integer(i)
				--io.put_integer(c)
				
				if not i.is_equal(1) then
					width := size.substring(1, i - 1)
				else
					width := "0"
				end
				
				if not i.is_equal(c) then
					height := size.substring(i + 1, c)
				else
					height := "0"
				end

				--io.put_string(width)
				--io.put_string(height)

				tup := [width.to_integer, height.to_integer]
				Result := tup
			else
				io.put_string("Unable to get the components %N")
			end
		end

	components_of_size (size: STRING): TUPLE[INTEGER, INTEGER]
		do
			Result := components_of (size, 'x')
		end

	components_of_position (size: STRING): TUPLE[INTEGER, INTEGER]
		do
			Result := components_of (size, ',')
		end

	components_of_minmax (size: STRING): TUPLE[INTEGER, INTEGER]
		do
			Result := components_of (size, ':')
		end

	components_of_limits (limits: STRING): TUPLE[INTEGER, INTEGER, INTEGER, INTEGER]
		local
			i, c: INTEGER
			xmin, xmax, ymin, ymax: STRING
			tup: TUPLE[INTEGER, INTEGER, INTEGER, INTEGER]
		do
			i := limits.index_of(':', 1)
			c := limits.count

			if not i.is_equal(1) then
				xmin := limits.substring(1, i - 1)
				limits.remove_substring(1, i)
			else
				xmin := "0"
				limits.remove_prefix(":")
			end

			i := limits.index_of(':', 1)

			if not i.is_equal(1) then
				xmax := limits.substring(1, i - 1)
				limits.remove_substring(1, i)
			else
				xmax := "0"
				limits.remove_prefix(":")
			end

			i := limits.index_of(':', 1)

			if not i.is_equal(1) then
				ymin := limits.substring(1, i - 1)
				limits.remove_substring(1, i)
			else
				ymin := "0"
				limits.remove_prefix(":")
			end
				
			ymax := limits

			tup := [xmin.to_integer, xmax.to_integer,
			        ymin.to_integer, ymax.to_integer]
			Result := tup
		end

	is_valid_string_date (value: STRING): BOOLEAN
		local
			str: STRING
			an_array: ARRAY[STRING]
			y, m, d: INTEGER
		do
			create str.copy(value)
			
			if str.occurrences('/').is_equal(2) then

				str.replace_all('/', ' ')
				an_array := str.split

				if an_array.count.is_equal(3) then
					if an_array.item(1).is_integer and
						an_array.item(2).is_integer and
						an_array.item(3).is_integer then

						y := an_array.item(1).to_integer
						m := an_array.item(2).to_integer
						d := an_array.item(3).to_integer

						if y >= 0 and
							m >= 1 and m <= 12 and
							d >= 1 and d <= 31 then
							
							Result := True
						else
							Result := False
						end
					else
						Result := False
					end
				else
					Result := False
				end
			else
				Result := False
			end
		end

	convert_date_to_tuple (value: STRING): TUPLE[INTEGER, INTEGER, INTEGER]
		local
			str: STRING
			an_array: ARRAY[STRING]
		do
			create str.copy(value)

			str.replace_all('/', ' ')
			an_array := str.split

			if an_array.count.is_equal(3) then
				if an_array.item(1).is_integer and
					an_array.item(2).is_integer and
					an_array.item(3).is_integer then
					
					Result := [an_array.item(1).to_integer,
								  an_array.item(2).to_integer,
								  an_array.item(3).to_integer]
					
				end
			end
		end

end

-- The MIT License (MIT)

-- Copyright (c) 2016, 2017, 2019, 2022 by German A. Arias

-- Permission is hereby granted, free of charge, to any person obtaining a copy
-- of this software and associated documentation files (the "Software"), to deal
-- in the Software without restriction, including without limitation the rights
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-- copies of the Software, and to permit persons to whom the Software is
-- furnished to do so, subject to the following conditions:
--
-- The above copyright notice and this permission notice shall be included in 
-- all copies or substantial portions of the Software.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-- SOFTWARE.
